home *** CD-ROM | disk | FTP | other *** search
- /* xlfio.c - xlisp file i/o */
- /* Copyright (c) 1985, by David Michael Betz
- All Rights Reserved
- Permission is granted for unrestricted non-commercial use */
-
- #include "xlisp.h"
-
- #ifdef MEGAMAX
- overlay "io"
- #endif
-
- /* external variables */
- extern NODE *s_stdin,*s_stdout,*true;
- extern NODE ***xlstack;
- extern int xlfsize;
- extern char buf[];
-
- /* external routines */
- extern FILE *fopen();
-
- /* forward declarations */
- FORWARD NODE *printit();
- FORWARD NODE *flatsize();
- FORWARD NODE *openit();
-
- /* xread - read an expression */
- NODE *xread(args)
- NODE *args;
- {
- NODE ***oldstk,*fptr,*eof,*rflag,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&fptr,&eof,NULL);
-
- /* get file pointer and eof value */
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
- eof = (args ? xlarg(&args) : NIL);
- rflag = (args ? xlarg(&args) : NIL);
- xllastarg(args);
-
- /* read an expression */
- if (!xlread(fptr,&val,rflag != NIL))
- val = eof;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the expression */
- return (val);
- }
-
- /* xprint - built-in function 'print' */
- NODE *xprint(args)
- NODE *args;
- {
- return (printit(args,TRUE,TRUE));
- }
-
- /* xprin1 - built-in function 'prin1' */
- NODE *xprin1(args)
- NODE *args;
- {
- return (printit(args,TRUE,FALSE));
- }
-
- /* xprinc - built-in function princ */
- NODE *xprinc(args)
- NODE *args;
- {
- return (printit(args,FALSE,FALSE));
- }
-
- /* xterpri - terminate the current print line */
- NODE *xterpri(args)
- NODE *args;
- {
- NODE *fptr;
-
- /* get file pointer */
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
- xllastarg(args);
-
- /* terminate the print line and return nil */
- xlterpri(fptr);
- return (NIL);
- }
-
- /* printit - common print function */
- LOCAL NODE *printit(args,pflag,tflag)
- NODE *args; int pflag,tflag;
- {
- NODE ***oldstk,*fptr,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&fptr,&val,NULL);
-
- /* get expression to print and file pointer */
- val = xlarg(&args);
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
- xllastarg(args);
-
- /* print the value */
- xlprint(fptr,val,pflag);
-
- /* terminate the print line if necessary */
- if (tflag)
- xlterpri(fptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result */
- return (val);
- }
-
- /* xflatsize - compute the size of a printed representation using prin1 */
- NODE *xflatsize(args)
- NODE *args;
- {
- return (flatsize(args,TRUE));
- }
-
- /* xflatc - compute the size of a printed representation using princ */
- NODE *xflatc(args)
- NODE *args;
- {
- return (flatsize(args,FALSE));
- }
-
- /* flatsize - compute the size of a printed expression */
- LOCAL NODE *flatsize(args,pflag)
- NODE *args; int pflag;
- {
- NODE ***oldstk,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&val,NULL);
-
- /* get the expression */
- val = xlarg(&args);
- xllastarg(args);
-
- /* print the value to compute its size */
- xlfsize = 0;
- xlprint(NIL,val,pflag);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the length of the expression */
- return (cvfixnum((FIXNUM)xlfsize));
- }
-
- /* xopeni - open an input file */
- NODE *xopeni(args)
- NODE *args;
- {
- return (openit(args,"r"));
- }
-
- /* xopeno - open an output file */
- NODE *xopeno(args)
- NODE *args;
- {
- return (openit(args,"w"));
- }
-
- /* openit - common file open routine */
- LOCAL NODE *openit(args,mode)
- NODE *args; char *mode;
- {
- NODE *fname,*val;
- char *name;
- FILE *fp;
-
- /* get the file name */
- fname = xlarg(&args);
- xllastarg(args);
-
- /* get the name string */
- if (symbolp(fname))
- name = getstring(getpname(fname));
- else if (stringp(fname))
- name = getstring(fname);
- else
- xlfail("bad argument type",fname);
-
- /* try to open the file */
- if ((fp = fopen(name,mode)) != NULL)
- val = cvfile(fp);
- else
- val = NIL;
-
- /* return the file pointer */
- return (val);
- }
-
- /* xclose - close a file */
- NODE *xclose(args)
- NODE *args;
- {
- NODE *fptr;
-
- /* get file pointer */
- fptr = xlmatch(FPTR,&args);
- xllastarg(args);
-
- /* make sure the file exists */
- if (getfile(fptr) == NULL)
- xlfail("file not open");
-
- /* close the file */
- fclose(getfile(fptr));
- setfile(fptr,NULL);
-
- /* return nil */
- return (NIL);
- }
-
- /* xrdchar - read a character from a file */
- NODE *xrdchar(args)
- NODE *args;
- {
- NODE *fptr;
- int ch;
-
- /* get file pointer */
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
- xllastarg(args);
-
- /* get character and check for eof */
- return ((ch = xlgetc(fptr)) == EOF ? NIL : cvfixnum((FIXNUM)ch));
- }
-
- /* xpkchar - peek at a character from a file */
- NODE *xpkchar(args)
- NODE *args;
- {
- NODE *flag,*fptr;
- int ch;
-
- /* peek flag and get file pointer */
- flag = (args ? xlarg(&args) : NIL);
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
- xllastarg(args);
-
- /* skip leading white space and get a character */
- if (flag)
- while ((ch = xlpeek(fptr)) != EOF && isspace(ch))
- xlgetc(fptr);
- else
- ch = xlpeek(fptr);
-
- /* return the character */
- return (ch == EOF ? NIL : cvfixnum((FIXNUM)ch));
- }
-
- /* xwrchar - write a character to a file */
- NODE *xwrchar(args)
- NODE *args;
- {
- NODE *fptr,*chr;
-
- /* get the character and file pointer */
- chr = xlmatch(INT,&args);
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
- xllastarg(args);
-
- /* put character to the file */
- xlputc(fptr,(int)getfixnum(chr));
-
- /* return the character */
- return (chr);
- }
-
- /* xreadline - read a line from a file */
- NODE *xreadline(args)
- NODE *args;
- {
- NODE ***oldstk,*fptr,*str,*newstr;
- int len,blen,ch;
- char *p,*sptr;
-
- /* create a new stack frame */
- oldstk = xlsave(&fptr,&str,NULL);
-
- /* get file pointer */
- fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
- xllastarg(args);
-
- /* get character and check for eof */
- len = blen = 0; p = buf;
- while ((ch = xlgetc(fptr)) != EOF && ch != '\n') {
-
- /* check for buffer overflow */
- if (blen >= STRMAX) {
- newstr = newstring(len+STRMAX);
- sptr = getstring(newstr); *sptr = 0;
- if (str) strcat(sptr,getstring(str));
- *p = 0; strcat(sptr,buf);
- p = buf; blen = 0;
- len += STRMAX;
- str = newstr;
- }
-
- /* store the character */
- *p++ = ch; blen++;
- }
-
- /* check for end of file */
- if (len == 0 && p == buf && ch == EOF) {
- xlstack = oldstk;
- return (NIL);
- }
-
- /* append the last substring */
- if (str == NIL || blen) {
- newstr = newstring(len+blen);
- sptr = getstring(newstr); *sptr = 0;
- if (str) strcat(sptr,getstring(str));
- *p = 0; strcat(sptr,buf);
- str = newstr;
- }
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the string */
- return (str);
- }